Skip to main content link. Accesskey S
  • HCL Logo
  • HCL Notes and Domino wiki
  • THIS WIKI IS READ-ONLY. Individual names altered for privacy purposes.
  • HCL Forums and Blogs
  • Home
  • Product Documentation
  • Community Articles
  • Learning Center
  • API Documentation
Search
API Documentation > App dev > Generating LTPA tokens using a Java servlet
  • Share Show Menu▼
  • Subscribe Show Menu▼

Recent articles by this author

IBM Lotus Notes 8.5.3 Traveler Upgrade Pack 1 in High-Availability configuration performance

This article reports the performance test results of a IBM Lotus Notes Traveler 8.5.3 Upgrade Pack 1 in High Availability (HA) configuration on Microsoft Windows 64-bit with both IBM DB2 in HA Disaster Recovery configuration and Microsoft SQL database with mirroring.

Configuring Microsoft Windows single sign-on for Web clients in an existing IBM Lotus Domino environment

This article is a simplified guide of the steps to configure Microsoft Windows Single Sign-on with IBM Lotus Domino. Using this guide, you can get your environment running in just a few minutes, even if you do not have in-depth knowledge of either the Trust Association Interceptor operation mode ...

Generating LTPA tokens using a Java servlet

This article describes the detailed steps to generate a Lightweight Third-Party Authentication (LTPA) token, using a JavaTM client running in an application server other than IBM® WebSphere® Portal.

Configuring SSL encryption for IBM Lotus Domino 8.5.1

This article provides the detailed steps on how to configure Secure Sockets Layer (SSL) encryption for IBM® Lotus® Domino® 8.5.1.

Comparing IBM Lotus Notes widgets with other widget types

This article introduces the often-confused concepts of widgets, Web widgets, Google Gadgets, iWidgets, and IBM® Lotus® Notes® widgets. Using some practical examples, we compare the differences and relationships among these five concepts, demonstrating the convenience offered by Notes ...
Community articleGenerating LTPA tokens using a Java servlet
Added by ~Fred Cistumipulings | Edited by ~Wendy Quethipilyynds on August 2, 2012 | Version 6
  • Actions Show Menu▼
expanded Abstract
collapsed Abstract
This article describes the detailed steps to generate a Lightweight Third-Party Authentication (LTPA) token, using a JavaTM client running in an application server other than IBM® WebSphere® Portal.
Tags: 8.5, authentication, API, Java
ShowTable of Contents
HideTable of Contents
  • 1 Introduction
  • 2 Getting started
  • 3 Generating the DLL
  • 4 Configuring project settings
    • 4.1 Creating and adding the C function
  • 5 Alternate approach
  • 6 Conclusion
  • 7 Resources
  • 8 About the authors

Introduction


The Lightweight Third-Party Authentication (LTPA) token was developed by IBM® as a Single Sign-on (SSO) technology for their WebSphere® and Lotus® Domino® product suite. The JavaTM Software Development Kit (SDK) that ships with Lotus Domino includes an API that allows a developer to access data in a Lotus Domino database via a Java client.

The Java API provides mechanisms to access the Lotus Domino database both within the Domino runtime and remotely, using the Domino Internet Inter-ORB Protocol (DIIOP) protocol. DIIOP therefore allows Java application developers to build applications that can use a Domino server as their data store without actually being hosted within the Domino server’s runtime.

All remote protocols must address the issue of security, and the Java DIIOP API supports the IBM-proprietary LTPA security mechanism. Most IBM application servers (for example, WebSphere and Domino) support LTPA out-of-the-box. However, if you're using a non-IBM application server, you may want an authentication mechanism other than LTPA, which then poses a problem at the data tier when accessing the Domino database.

Unless data in the Domino database can be accessed anonymously, you must use a username and password or an LTPA token when creating the Domino session for data access.

The username and password used to log into the Web application may be different than the credentials used to access the Domino database, requiring a credentials translation layer. This translation layer ideally would not store a new set of user passwords since passwords change fairly often, introducing a maintenance headache.

Instead, we only need to maintain a log-in ID mapping, to use an LTPA-token-based solution, because encrypted LTPA tokens only store a user’s log-in ID and not their password.

This article details how to generate the LTPA token by using a Java client running in an application server other than WebSphere. WebSphere already has built-in support for LTPA token generation, therefore making this approach redundant.

Getting started


This article discusses how to create a Java servlet (henceforth referred to as the LTPA servlet) to generate LTPA tokens. This is a robust solution that can be used by many different Web applications that rely on the Domino database as their data store. Using inbound firewall rules, we can protect the LTPA servlet so as to allow only the appropriate Web applications to access it.

This LTPA servlet can be packaged in a Web application archive (WAR) file and run on a variety of application servers (JBoss, Tomcat, Jetty, etc.). This article is not intended to be a tutorial on creating servlets and WAR files. It is assumed the reader is already familiar with these technologies; instead, we'll discuss creating a Dynamic Link Library (DLL) for LTPA token generation.

The Lotus C API toolkit contains functions encapsulated in DLLs for generating an LTPA token. No comparable methods were found in the Java SDK that ships with Lotus Domino or with WebSphere Application Server (i.e. Notes.jar), so first we write a function in C that can then be called from the LTPA servlet.

The LTPA servlet uses Java Native Access (JNA) to access a DLL containing the C function. This is a Microsoft® Windows® solution, but a similar strategy could be used on UNIX® by creating a Shared Object Library instead of a DLL. The instructions below show how to generate the DLL as a debug build.

Generating the DLL


First, we use Microsoft Visual C++ 2010 Express to generate the DLL by following these steps:
  1. Create a New Project by selecting File --- New --- Project.
  2. Select “Win32 Console Application,” and enter the name of the project; click OK (see figure 1).
Figure 1. New Project window



3. The Win32 Application Wizard Welcome window displays; click Next (see figure 2).

Figure 2. Win32 Application Wizard Welcome window



4. In the Application Settings window, select the DLL radio button and click Finish (see figure 3).

Figure 3. Application Settings window


Configuring project settings


To do this:
  1. Select Project --- LtpaProject Properties, expand Configuration Properties, and select VC++ Directories (see figure 4).
  2. Add to the Include Directories and Library Directories the directories for the include files and lib files, respectively, for the Lotus C API toolkit (use the 8.5 version). Click OK.
Figure 4. LtpaToken Property Pages window



3. Select Configuration Properties --- C/C++ --- Code Generation, and make sure the Runtime Library property is set to Multi-threaded (/MT), as shown in figure 5.

Figure 5. Runtime Library set to Multi-threaded (/MT)



4. Next, select Configuration Properties --- C/C++ --- Command Line, and add /D “W32” in the Additional Options section (see figure 6).

Figure 6. Add /D “W32” in Additional Options section



5. Finally, select Configuration Properties --- Linker --- Input, and add notes.lib (from the Lotus C API toolkit) to the Additional Dependencies property (see figure 7). Click OK.

Figure 7. Add notes.lib to Additional Dependencies property

Creating and adding the C function


Now, the C function must be created and added to the DLL project.

Listings 1 and 2 show the contents that should be in the include file and C file that generate the LTPA token.

Listing 1. LtpaToken.h

extern "C" __declspec(dllexport) int CreateLtpaToken(char *username, char *ltpaToken, char *errorMessage);


Listing 2. LtpaToken.cpp

// LtpaToken.cpp : Defines the exported functions for the DLL application.
 
#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "global.h"
#include "osfile.h"
#include "bsafe.h"
#include "osmisc.h"
#include "osmem.h"
#include "LtpaToken.h"

extern "C" __declspec(dllexport) int CreateLtpaToken(char far *username, char far *ltpaToken, char *errorMessage)
{          
            STATUS   errorStatus = NOERROR;    
            char notesError[255];
           
            if (error = NotesInit()) {
                        OSLoadString(NULLHANDLE, ERR(error), notesError, 255);
                        printf("error = %s\n", notesError);
                        strcpy(errorMessage, notesError);
                        return errorStatus;
            }
           
            MEMHANDLE mhToken;
            error = SECTokenGenerate(NULL, NULL, "LtpaToken", username, 0, 0, &mhToken, (DWORD)0, (void *)NULL);
            if(error != NOERROR) {
                        OSLoadString(NULLHANDLE, ERR(error), szNotesError, 255);
                        printf("error = %s\n", szNotesError);
                        strcpy(errorMessage, szNotesError);
                        return error;
            } else {
                        SSO_TOKEN *ssoToken = (SSO_TOKEN*)OSMemoryLock(mhToken);
                        char *pData = (char*)OSMemoryLock(ssoToken->mhData);
                        strcpy(ltpaToken, pData);
                        SECTokenFree(&mhToken);
            }
 
            NotesTerm();
            return 0;
}


The C code above calls out to an external function called SECTokenGenerate whose implementation is included in the Notes C API. Details of that function can be found in the document, “SECTokenGenerate - Generate a Single Sign-On Token.”

At last, the project can be built and the DLL created. To do this, select Debug --- Build Solution; the resulting DLL can be found in the Debug directory of the project.

The LTPA servlet can now be created and will call out to the LtpaToken.dll that was just created (see listing 3).

Listing 3. LtpaServlet.java

import javax.servlet.*;
import lotus.domino.*;
import com.sun.jna.*;
 
public class LtpaServlet extends HttpServlet
{
      public static final String USERNAME_PARAM = "un";
      private byte[] ltpaToken = new byte[2048];
      private byte[] errorMessage = new byte[255];
     
      // The method signature defined below must match that defined in the DLL for the C function

      interface LtpaTokenInterface extends StdCallLibrary {
      	int CreateLtpaToken(String username, byte[] ltpaToken, byte[] errorMessage);
      }
     
      public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        	response.setContentType("text/html");
        	ServletOutputStream out = response.getOutputStream();
        	String username = request.getParameter(USERNAME_PARAM);
 
        	if (username != null)) {
		try {
            			Native.setProtected(true);
                        		LtpaTokenInterface ltpaTokenDll = (LtpaTokenInterface)
                                                                                                      Native.loadLibrary("LtpaToken", LtpaToken.class);
                             	int error = ltpaTokenDll.CreateLtpaToken(username, ltpaToken, errorMessage);
                              	if(error == 0) {
                                   		out.println(Native.toString(ltpaToken));
                              	} else {
                                   		out.println("Error creating LTPA token.");
                                    		out.println("Error message: " + Native.toString(errorMessage));
                              	}
            		} catch(Exception e) {	
                  		out.println("Error creating LTPA token.");
                        		out.println("Error message: " + e.toString());
            		}
        	} else {
            		out.println("No parameter ‘" +  USERNAME_PARAM + "’ passed to servlet ");
        	}
    }
 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
    {
	doPost(request, response);
    }
}


Listing 4 shows the web.xml configurations necessary for your Web application to expose the new servlet.

Listing 4. web.xml file for servlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
            xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
            <display-name>LTPA Token Servlet</display-name>
            <welcome-file-list>
                        <welcome-file>index.html</welcome-file>
            </welcome-file-list>
            <servlet>
                        <servlet-name>LtpaTokenServlet</servlet-name>
                        <servlet-class>LtpaTokenServlet</servlet-class>
            </servlet>
            <servlet-mapping>
                        <servlet-name>LtpaTokenServlet</servlet-name>
                        <url-pattern>/ltpaTokenServlet</url-pattern>
            </servlet-mapping>
</web-app>

Alternate approach


The LTPA Token generation technique discussed above uses a custom DLL as well as DLLs provided by the Lotus toolkit to ultimately generate the LTPA token. Behind the scenes, when the SECTokenGenerate function is called, a series of other Lotus-provided DLLs will also be loaded and called, and hence those DLLs must be accessible (in the example above, those DLLs are simply found where the Domino server is installed, for example, C:\Lotus\Domino).

In addition to the DLLs, a special Domino document within the standard Names.nsf Domino database, called WebSSOConfig, is opened to retrieve the server’s LTPA private key. That key is then used to encrypt the LTPA token. If, for some reason, this lookup for Names.nsf fails, you might see debug output like so:
"ERROR: when reading configuration [Domino Directory does not exist]."
Hosting the LTPA servlet on the same machine as the Domino server may not always be the best architectural decision---or may not even be possible. For example, instances were found using Domino Server 6.5 in which, when it was configured to use Directory Assistance, it could lock the local Names.nsf while the server was running, causing the DLL SecTokenGenerate function call to fail to generate the LTPA token.

Although stopping the Domino server fixed the problem (unlocked Names.nsf), that is obviously not a viable solution. However, it is possible to make a portable LTPA-token-generating application that is derived from an existing Domino server install.

This alternate approach is described as follows:

Instead of relying on the DLLs to gain access to the single Names.nsf file in use while the Domino Server is running, we can construct a standalone application that uses a copy of Names.nsf and, with some additional DLLs, can be hosted on any Windows operating system (the software was tested on both Windows Server 2000/2003/2008, as well as Windows XP).

Note that, if you're deploying this solution to a 64-bit Windows server machine, make sure that your Java application is using a 32-bit JRE and not 64-bit.

To create the standalone application, copy from your Domino install directory the following files to a new location within your portable LtpaToken servlet’s classpath (for a Web application, this is simply the WEB-INF\lib directory):
  • icudt18l.dat
  • ltsci3.tlb
  • js32.dll
  • ndgts.dll
  • nlsccstr.dll
  • nnotes.dll
  • nxmlcommon.dll
  • nxmlpar.dll
  • LtpaToken.dll (This is the custom DLL compiled in the previous section.)
  • The ID file that the Domino server uses to access Names.nsf. (This is usually the name of the Domino Server with “.ID” appended to it.)
  • Names.nsf. When copying Names.nsf, be sure to replace it in the future with a fresh copy should the original Names.nsf's Domino LTPA private key needs to be regenerated. Otherwise, any LTPA tokens the servlet generates will not be accepted by the Domino server (it will be unable to decrypt them).
In addition, you need to create a Notes.ini file that is used by the DLLs to locate the other DLLs used when SecTokenGenerate is called. This new Notes.ini should also be copied to the lib directory and should contain the following content (no more is needed):

[Notes]
Directory=<full path to your lib directory>
NotesProgram=<full path to your lib directory>
KeyFilename=<the filename of the ID file used to access names.nsf>

Once this is done, you can host the LtpaTokenServlet on any Windows machine, even one that does not have a Domino server installed, as long as the lib folder is part of your Java app’s classpath. Also, make sure to add the path to the lib folder to the Windows machine’s PATH environment variable.

Conclusion


This article has demonstrated that the Lotus C API toolkit can be used to generate an LTPA token without the need for the Domino user’s password. Instead, by just using a log-in ID we can generate an LTPA token by a Java servlet, using JNA to access a custom DLL that in turn accesses the underlying Domino server’s LTPA token generation engine. The LTPA token can then be used by any other application that needs to authenticate with a Domino server.

Resources


developerWorks® WebSphere Portal zone:
http://www.ibm.com/developerworks/websphere/zones/portal/

developerWorks Lotus Notes and Domino product page:
http://www.ibm.com/developerworks/lotus/products/notesdomino/

WebSphere Portal forum:
http://www.ibm.com/developerworks/forums/forum.jspa?forumID=168

Notes/Domino 8 forum:
http://www-10.lotus.com/ldd/nd8forum.nsf?OpenDatabase

About the authors


Jason Everhart has worked in the software industry for 18 years, the last 4 of which as an independent software consultant. He is currently working as a consultant for Techflow, Inc., in San Diego, California.

Paul Spinelli is a Senior Application Developer working for TechFlow, Inc., in San Diego. Since graduating from the University of Virginia with a computer science degree, Paul has worked as a software developer for over 13 years. His experience has brought him an in-depth knowledge of various programming languages, OOP techniques, and security technologies.


  • Actions Show Menu▼


expanded Attachments (0)
collapsed Attachments (0)
Edit the article to add or modify attachments.
expanded Versions (1)
collapsed Versions (1)
Version Comparison     
VersionDateChanged by              Summary of changes
This version (6)Aug 2, 2012, 8:16:25 PM~Wendy Quethipilyynds  
expanded Comments (0)
collapsed Comments (0)
Copy and paste this wiki markup to link to this article from another article in this wiki.
Go ElsewhereStay ConnectedAbout
  • HCL Software
  • HCL Digital Solutions community
  • HCL Software support
  • BlogsDigital Solutions blog
  • Community LinkHCL Software forums and blogs
  • About HCL Software
  • Privacy
  • Accessibility